package com.xiaode.controller.admin.account;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.json.JSONUtil;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.jfinal.aop.Before;
import com.jfinal.kit.*;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;
import com.jfinal.plugin.activerecord.tx.Tx;
import com.jfinal.plugin.redis.Cache;
import com.jfinal.plugin.redis.Redis;
import com.xiaode.common.constant.Const;
import com.xiaode.common.model.*;
import com.xiaode.common.model.dto.ParentInfoDTO;
import com.xiaode.common.model.dto.StudentPageDTO;
import com.xiaode.common.model.dto.exportMember.AdminInfoDTO;
import com.xiaode.common.model.dto.exportMember.StudentInfoDTO;
import com.xiaode.exce.EnumError;
import com.xiaode.plugin.influx.InfluxDbKit;
import com.xiaode.util.ChatUtil;
import com.xiaode.util.FilterUtil;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.locks.ReentrantLock;
import java.util.stream.Collectors;

public class AccountService {

//    private static HashMap<String, List> taskMap = new HashMap<>();
    private static HashMap<Integer, String> roleMap = new HashMap<>();
    public static ReentrantLock reentrantLock = new ReentrantLock(true);

    static {
        //初始化静态map集合
//        findTaskList();
        //初始化所有角色id,名字map集合
        List<Role> all = Role.dao.findAll();
        for (Role role : all) {
            roleMap.put(role.getId(), role.getName());
        }
    }

//    public static void findTaskList() {
//        //查询需要生成的任务
//        List<CurrencyEvaTask> currencyEvaTasks_1 = CurrencyEvaTask.dao.find("select id,type,score,sonContent from currency_eva_task where cycle = ?", 1);
//        List<CurrencyEvaTask> currencyEvaTasks_2 = CurrencyEvaTask.dao.find("select id,type,score,sonContent from currency_eva_task where cycle = ?", 2);
//        List<CurrencyEvaTask> currencyEvaTasks_3 = CurrencyEvaTask.dao.find("select id,type,score,sonContent from currency_eva_task where cycle = ?", 3);
//        List<CurrencyTask> currencyTasks_1 = CurrencyTask.dao.find("select id,sonContent,type,score from currency_task where cycle = ?", 1);
//        List<CurrencyTask> currencyTasks_2 = CurrencyTask.dao.find("select id,sonContent,type,score from currency_task where cycle = ?", 2);
//        List<CurrencyTask> currencyTasks_3 = CurrencyTask.dao.find("select id,sonContent,type,score from currency_task where cycle = ?", 3);
//        taskMap.put("evaTask1", currencyEvaTasks_1);
//        taskMap.put("evaTask2", currencyEvaTasks_2);
//        taskMap.put("evaTask3", currencyEvaTasks_3);
//        taskMap.put("task1", currencyTasks_1);
//        taskMap.put("task2", currencyTasks_2);
//        taskMap.put("task3", currencyTasks_3);
//    }

    /**
     * 教师成员管理
     *
     * @param account
     * @param name
     * @param state
     * @param page
     * @param limit
     * @param roleId
     * @return
     * @throws Exception
     */
    public Ret adminAccountPage(Admin myAdmin, String account, String name, Integer state, Integer page, Integer limit, Integer roleId, String accountSort, Integer loginDuration, String lastLoginTimeSort) throws Exception {

        Cache redis = Redis.use();
        ArrayList<String> strlist = new ArrayList<>();
        Set<String> keys = redis.keys(Const.user.Admin + "*");
        Iterator<String> keyIterator = keys.iterator();
        //查询所有admin用户,包含时间戳
        ArrayList<Admin> admins = new ArrayList<>();
        while (keyIterator.hasNext()) {
            String next = keyIterator.next();
            admins.add(redis.get(next));
        }
        //去除测试账户
        Prop use = PropKit.use("testAccount.properties");
        String adminAccount = use.get("adminAccount");
        List<String> adminTestAccountList = Arrays.asList(adminAccount.split(","));
        //对用户进行处理过滤排序
        String finalAccount = account;
        String finalName = name;
        List<Admin> collect = admins.stream().filter(admin -> {
            if (StrUtil.isNotEmpty(finalAccount) && !FilterUtil.filterStr(admin.getJobNum(), finalAccount)) {
                return false;
            }
            if (StrUtil.isNotEmpty(finalName) && !FilterUtil.filterStr(admin.getName(), finalName)) {
                return false;
            }
            if (roleId != null && !JSONUtil.toList(admin.getRoleIds(), Integer.class).contains(roleId)) {
                return false;
            }
            if (state != null && !admin.getState().equals(state)) {
                return false;
            }
            if (adminTestAccountList.contains(admin.getAccountId().toString())) {
                return false;
            }
            if (admin.getUserType() == null || admin.getUserType() == 0){
                return false;
            }
            return true;
        }).sorted((e1, e2) -> {
            if (StrUtil.isNotEmpty(accountSort)) {
                if (accountSort.equals("asc")) {
                    //清除集合
                    strlist.clear();
                    strlist.add(e1.getJobNum());
                    strlist.add(e2.getJobNum());
                    Collections.sort(strlist);
                    return strlist.get(0).equals(e1.getJobNum()) ? 1 : -1;
                } else {
                    //清除集合
                    strlist.clear();
                    strlist.add(e1.getJobNum());
                    strlist.add(e2.getJobNum());
                    Collections.sort(strlist);
                    return strlist.get(0).equals(e1.getJobNum()) ? -1 : 1;
                }
            }
            if (StrUtil.isNotEmpty(lastLoginTimeSort)) {
//                if (lastLoginTimeSort.equalsIgnoreCase("asc")) {
//                    return (int) (e1.getLong("timeStamp") / 1000 - e2.getLong("timeStamp") / 1000);
//                } else {
//                    return (int) (e2.getLong("timeStamp") / 1000 - e1.getLong("timeStamp") / 1000);
//                }
                Double zscore1 = redis.zscore(Const.user.lastLoginTimeT, e1.getId());
            	Double zscore2 = redis.zscore(Const.user.lastLoginTimeT, e2.getId());
                if (lastLoginTimeSort.equalsIgnoreCase("asc")) {
//                    return (int) (e1.getLong("lastLoginTimestamp") / 1000 - e2.getLong("lastLoginTimestamp") / 1000);
                	return (int) ((zscore1==null?0:zscore1) / 1000 - (zscore2==null?0:zscore2) / 1000);
                } else {
//                    return (int) (e2.getLong("lastLoginTimestamp") / 1000 - e1.getLong("lastLoginTimestamp") / 1000);
                	return (int) ((zscore2==null?0:zscore2) / 1000 - (zscore1==null?0:zscore1) / 1000);
                }
            }
            return e2.getId() - e1.getId();
        }).collect(Collectors.toList());
        int size = collect.size();
        List<Admin> resList = collect.stream().skip((page - 1) * limit).limit(limit).collect(Collectors.toList());
        for (int i = 0; i < resList.size(); i++) {
            Admin admin = resList.get(i);
            
            
            Double zscore = redis.zscore(Const.user.lastLoginTimeT, admin.getId());
//            Long timeStamp = admin.getLong("timeStamp");
            if(zscore != null && zscore.intValue() != 0) {
            	Long timeStamp = zscore.longValue();
            	admin.setLastLoginTime(new Date(timeStamp).toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime());
            }else {
            	admin.setLastLoginTime(null);
            }
            
//            if (BeanUtil.isNotEmpty(timeStamp) && timeStamp != 0) {
//                admin.setLastLoginTime(new Date(timeStamp).toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime());
//            } else {
//                admin.setLastLoginTime(null);
//            }
            
            if (admin.getLastLoginTime() != null) {
                admin.put("isLogin", true);
            } else {
                admin.put("isLogin", false);
            }

            
            //查询登录时间
            if (loginDuration != null) {
                Long startTime = null;
                Long endTime = System.currentTimeMillis() / 1000;
                if (loginDuration == 2) {
                    Calendar calendar = Calendar.getInstance();
                    calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH) - 1, 0, 0, 0);
                    startTime = calendar.getTime().getTime() / 1000;
                    Calendar instance = Calendar.getInstance();
                    instance.set(instance.get(Calendar.YEAR), instance.get(Calendar.MONTH), instance.get(Calendar.DAY_OF_MONTH) - 1, 23, 59, 59);
                    endTime = instance.getTime().getTime() / 1000;
                } else if (loginDuration == 3) {
                    Calendar calendar = Calendar.getInstance();
                    calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH) - 6, 0, 0, 0);
                    startTime = calendar.getTime().getTime() / 1000;
                } else if (loginDuration == 4) {
                    Calendar calendar = Calendar.getInstance();
                    calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH) - 29, 0, 0, 0);
                    startTime = calendar.getTime().getTime() / 1000;
                } else {
                    long current = System.currentTimeMillis();
                    startTime = (current - (current + TimeZone.getDefault().getRawOffset()) % (1000 * 3600 * 24)) / 1000;
                }
                //查询登录时长
                int statisticsUseTime = InfluxDbKit.statisticsUseTime("tlog", admin.getId(), startTime.toString(), endTime.toString());
                admin.put("loginDuration", statisticsUseTime + "min");
            }
        }
        return Ret.ok("admins", resList).set("page", page).set("count", size % limit == 0 ? size / limit : size / limit + 1).set("totalrow", size);
    }

    /**
     * 编辑教师
     *
     * @param admin           当前用户
     * @param uAdminId        要编辑的用户id
     * @param account         教师工号
     * @param state           是否禁用
     * @param roleIds         角色
     * @return
     * @throws Exception
     */
    @Before(Tx.class)
    public Ret editAdmin(Admin admin, Integer uAdminId, String account, Integer state, String roleIds) throws Exception {
        //编辑属性全部为空
        if (StrUtil.isAllBlank( account, roleIds) && state == null) {
            return Ret.ok();
        }
        //查询当前id的用户
        List<Admin> uAdmin = Admin.dao.find("SELECT * FROM admin WHERE account = ? AND isDele = 0", account);
        if (uAdmin.isEmpty()) {
            return Ret.fail().set("error", EnumError.USER_NULL.getObj());
        }
        //设置工号
//        if (StrUtil.isNotBlank(account)) {
//            uAdmin.setAccount(account);
//        }
        //设置角色
        if (StrUtil.isNotBlank(roleIds)) {
            List<Integer> integers = JSONUtil.toList(roleIds, Integer.class);
            if (!integers.contains(2)) {
                integers.add(2);
            }
            uAdmin.stream().forEach(ad->ad.setRoleIds(JSONUtil.toJsonStr(integers)));
        }
        //设置密码
//        if (StrUtil.isNotBlank(password)) {
//            String salt = uAdmin.getSalt();
//            String hashedPass = HashKit.sha256(salt + password);
//            uAdmin.setPassword(hashedPass);
//        }
        if (state != null) {
            uAdmin.stream().forEach(ad->ad.setState(state));
        }
        Db.batchUpdate(uAdmin,uAdmin.size());
        //清缓存
        Cache redis = Redis.use();
        for (Admin ad : uAdmin) {
            boolean exists = redis.exists(Const.user.loginAdmin + ad.getAccountId());
            if (exists){
                Admin o = redis.get(Const.user.loginAdmin + ad.getAccountId());
                if (StrUtil.isNotBlank(account)) {
                    o.setJobNum(account);
                }
                //设置角色
                if (StrUtil.isNotBlank(roleIds)) {
                    List<Integer> integers = JSONUtil.toList(roleIds, Integer.class);
                    if (!integers.contains(2)) {
                        integers.add(2);
                    }
                    o.setRoleIds(JSONUtil.toJsonStr(integers));
                }
                if (state != null) {
                    o.setState(state);
                }
                redis.setex(Const.user.loginAdmin + ad.getAccountId(),Const.user.timeToLiveSeconds,o);
            }
        }


        //更新redis中数据
        for (Admin admin1 : uAdmin) {
            Admin o = redis.get(Const.user.Admin + admin1.getId());
            if (StrUtil.isNotEmpty(account)) {
                o.setJobNum(account);
            }
            if (state != null) {
                o.setState(state);
            }
            if (StrUtil.isNotBlank(roleIds)) {
                o.setRoleIds(roleIds);
            }
            redis.set(Const.user.Admin + admin1.getId(), o);
        }

        return Ret.ok();
    }

    /**
     * 删除教师
     *
     * @param admin    当前教师
     * @param adminIds 要删除的教师id列表
     * @return
     * @throws Exception
     */
//    @Before(Tx.class)
//    public Ret deleAdmin(Admin admin, String adminIds) throws Exception {
//        List<Integer> adIdList = JSONUtil.toList(adminIds, Integer.class);
//        //遍历处理
//        for (Integer adminId : adIdList) {
//            Admin uAdmin = Admin.dao.findById(adminId);
//            if (BeanUtil.isNotEmpty(uAdmin)) {
//                //删除群聊关系
//                List<ChatGroupUser> chatGroupUsers = ChatGroupUser.dao.find("SELECT * FROM chat_group_user WHERE userId = ? AND userType = 2", adminId);
//                List<Integer> list = chatGroupUsers.stream().map(chatGroupUser ->
//                        chatGroupUser.getChatGroupId()
//                ).collect(Collectors.toList());
//                //删除群聊
//                ChatUtil.deleGroups(uAdmin.getAccountId(), list);
//                //删除好友关系
//                List<Record> studentList = Db.find("SELECT stu.accountId FROM teacher_student ts INNER JOIN student stu ON ts.studentId = stu.id WHERE ts.teacherId = ? AND ts.state = 2", adminId);
//                if (ObjectUtil.isAllNotEmpty(studentList)) {
//                    List<Integer> collect = studentList.stream().map(record -> record.getInt("accountId")).collect(Collectors.toList());
//                    ChatUtil.deleFriends(uAdmin.getAccountId(), collect);
//                }
//
//                uAdmin.setIsDele(true);
//                uAdmin.update();
//                //删除数据权限
//                Db.delete("DELETE FROM data_permission WHERE teacherId = ?", adminId);
//                //删除架构管理
//                Db.delete("DELETE FROM org_admin WHERE adminId = ?", adminId);
//                //删除师生绑定
//                Db.delete("DELETE FROM teacher_student WHERE teacherId = ?", adminId);
//                //删除群聊
//                Db.delete("DELETE FROM chat_group_user WHERE userId = ? AND userType = 2", adminId);
//                Redis.use().del(Const.user.loginAdmin + uAdmin.getAccountId());
//            }
//            //删除admin
//            Redis.use().del(Const.user.Admin + adminId);
//        }
//        return Ret.ok();
//    }

    /**
     * 编辑学生
     *
     * @param admin      当前教师
     * @param studentId  学生id
     * @param state      是否禁用
     * @param teacherId  学生绑定的教师id
     * @return
     * @throws Exception
     */
    @Before(Tx.class)
    public Ret editStudent(Admin admin, Integer studentId,Integer state, Integer teacherId) throws Exception {
        //如果要修改的参数全部为空,直接返回
        if (ObjectUtil.isAllEmpty( state,teacherId)) {
            return Ret.ok();
        }
        Cache redis = Redis.use();
        Student o = redis.get(Const.user.Student + studentId);
        Student student = Student.dao.findById(studentId);
        if (student == null) {
            return Ret.fail().set("error", EnumError.USER_NULL.getObj());
        }
        //判断是否拥有数据权限
        HashSet<Integer> frameworkPermission = admin.get("frameworkPermission");
        if (frameworkPermission == null || !frameworkPermission.contains(student.getClasId()) || !frameworkPermission.contains(student.getClasId())) {
            return Ret.fail().set("error", EnumError.NOT_HAVE_AUTHORITY.getObj());
        }

        if (BeanUtil.isEmpty(student)) {
            return Ret.fail().set("error", EnumError.USER_NULL.getObj());
        }
        //设置状态
        if (state != null) {
            student.setState(state);
            o.setState(state);
        }
        //设置教师绑定关系
        if (teacherId != null) {
            TeacherStudent teacherStudent = TeacherStudent.dao.findFirst("SELECT * FROM teacher_student WHERE studentId = ?", studentId);
            ArrayList<Integer> list = new ArrayList<>();
            Admin admin3 = redis.get(Const.user.Admin + teacherId);
            if (BeanUtil.isEmpty(teacherStudent)) {
                Admin admin1 = Admin.dao.findById(teacherId);
                if (BeanUtil.isNotEmpty(admin1)) {
                    TeacherStudent teacherStudent1 = new TeacherStudent();
                    teacherStudent1.setTeacherId(teacherId);
                    teacherStudent1.setState(2);
                    teacherStudent1.setStudentId(studentId);
                    teacherStudent1.save();
                    //添加好友
                    list.add(admin3.getAccountId());
                    o.put("teacherId", teacherId);
                    o.put("teacher", admin1.getName());
                    ChatUtil.addFriends(o.getAccountId(), list);
                }
            } else {
                //删除之前好友关系
                list.add(admin3.getAccountId());
                ChatUtil.deleFriends(o.getAccountId(), list);
                teacherStudent.setTeacherId(teacherId);
                teacherStudent.setUpdateTime(LocalDateTime.now());
                teacherStudent.setState(2);
                o.put("teacherId", teacherId);
                Admin ad = Admin.dao.findById(teacherId);
                o.put("teacher", ad.getName());
                teacherStudent.update();
                //添加新的好友关系
                list.clear();
                list.add(admin3.getAccountId());
                ChatUtil.addFriends(o.getAccountId(), list);
            }
            //更新申请解绑/申请绑定的状态
            TeacherStudentLog teacherStudentLog = TeacherStudentLog.dao.findFirst("SELECT * FROM teacher_student_log WHERE studentId = ? AND state = 1", studentId);
            TsLog tsLog = new TsLog();
            if (BeanUtil.isNotEmpty(teacherStudentLog)) {
                teacherStudentLog.setState(4);
                teacherStudentLog.setExamineId(admin.getId());
                tsLog.setTeacherStudentLogId(teacherStudentLog.getId());
                teacherStudentLog.update();
            }
            //添加日志
            tsLog.setTeacherId(teacherId);
            tsLog.setStudentId(studentId);
            tsLog.setState(2);
            tsLog.setType(1);
            tsLog.setLogType(2);
            tsLog.save();

            //TODO  添加家校群聊
//            ChatGroup chatGroup = ChatGroup.dao.findFirst("SELECT cg.* FROM chat_group cg INNER JOIN chat_group_user cgu ON cg.id = cgu.chatGroupId AND cg.type = 3 WHERE cgu.userId = ? AND userType = 1", studentId);
//            if (BeanUtil.isNotEmpty(chatGroup)) {
//                ChatGroupUser first = ChatGroupUser.dao.findFirst("SELECT * FROM chat_group_user WHERE chatGroupId = ? AND userId = ? AND userType = 2", chatGroup.getId(), teacherId);
//                //如果教师不在当前群聊中
//                if (BeanUtil.isEmpty(first)) {
//                    ChatGroupUser chatGroupUser = new ChatGroupUser();
//                    chatGroupUser.setUserId(teacherId);
//                    chatGroupUser.setUserType(2);
//                    chatGroupUser.setChatGroupId(chatGroup.getId());
//                    chatGroupUser.setDisturb(1);
//                    chatGroupUser.setLevel(chatGroup.getLeaderId() == null ? 0 : 2);
//                    if (chatGroup.getLeaderId() == null) {
//                        chatGroup.setLeaderType(0);
//                        chatGroup.setLeaderId(teacherId);
//                        chatGroup.setVersion(chatGroup.getVersion() + 1);
//                        chatGroup.update();
//                    }
//                    redis.set(Const.chatService.userGroup + chatGroup.getId(), chatGroup);
//                    ArrayList<Integer> list1 = new ArrayList<>();
//                    list1.add(chatGroup.getId());
//                    chatGroupUser.save();
//                    ChatUtil.addGroups(admin3.getAccountId(), list1);
//                }
//            }
        }

        student.update();
        
        //更新缓存
        redis.setex(Const.user.loginStudent + student.getNumber(),Const.user.timeToLiveSeconds, o);
        redis.set(Const.user.Student + o.getId(), o);
        
        return Ret.ok();
    }

    /**
     * 重置学生密码
     *
     * @param admin     当前教师
     * @param studentId 学生id
     * @return
     * @throws Exception
     */
    public Ret resetStudentPass(Admin admin, Integer studentId) throws Exception {
        Student student = Student.dao.findFirst("SELECT * FROM student WHERE id = ? AND isDele = 0", studentId);
        //查询学生
        if (BeanUtil.isEmpty(student)) {
            return Ret.fail().set("error", EnumError.USER_NULL.getObj());
        }
        //查询数据权限
        Set<Integer> frameworkPermission = admin.get("frameworkPermission");
        if (!frameworkPermission.contains(student.getClasId())) {
            return Ret.fail().set("error", EnumError.NOT_HAVE_AUTHORITY.getObj());
        }

        UserAccount userAccount = UserAccount.dao.findById(student.getAccountId());
		String newPassword = SecureUtil.md5(SecureUtil.md5("111111") + userAccount.getId() + Const.salt);
		UserAccount ua = new UserAccount();
		ua.setId(student.getAccountId());
		ua.setPassword(newPassword);
		ua.update();
        
        Redis.use().del(Const.user.loginStudent + student.getNumber());
        return Ret.ok();
    }

    /**
     * 重置admin密码
     *
     * @param adminId
     * @return
     */
    public Ret resetAdminPass(Integer adminId) throws Exception {
        //查询当前用户
        Admin admin = Admin.dao.findById(adminId);
        if (BeanUtil.isEmpty(admin)) {
            return Ret.fail().set("error", EnumError.ACCOUNT_NO.getObj());
        }
        
        UserAccount userAccount = UserAccount.dao.findById(admin.getAccountId());
		String newPassword = SecureUtil.md5(SecureUtil.md5("111111") + userAccount.getId() + Const.salt);
		UserAccount ua = new UserAccount();
		ua.setId(admin.getAccountId());
		ua.setPassword(newPassword);
		ua.update();
        
        //清除redis缓存
        Redis.use().del(Const.user.loginAdmin + admin.getAccountId());
        return Ret.ok();
    }

    /**
     * 启用禁用admin
     *
     * @param state
     * @return
     */
    public Ret adminState(String adminIds, Integer state) throws Exception {
        Cache redis = Redis.use();
        //查询当前id用户
        List<Integer> adIdList = JSONUtil.toList(adminIds, Integer.class);
//        List<String> list = adIdList.stream().map(integer ->
//                {
//                    Admin o = redis.get(Const.user.Admin + integer);
//                    String account = o.getJobNum();
//                    return account;
//                }
//        ).collect(Collectors.toList());
        //查询所有账号
        if (adIdList.isEmpty()){
            return Ret.ok();
        }
        List<Integer> collect = Db.template("findAdminByAccountList", Kv.by("accountList", adIdList)).find().stream().map(record -> record.getInt("id")).collect(Collectors.toList());
        if(collect.size() > 0) {
        	Db.template("updateAdminState",Kv.by("idList",collect).set("state",state)).update();
            for (Integer adminId : collect) {
//                Admin admin = Admin.dao.findById(adminId);
//                if (BeanUtil.isEmpty(admin)) {
//                    return Ret.fail().set("error", EnumError.ACCOUNT_NO.getObj());
//                }
//                admin.setState(state);
//                admin.update();
                Admin o = redis.get(Const.user.Admin + adminId);
                if (BeanUtil.isEmpty(o)) {
                    return Ret.fail().set("error", EnumError.ACCOUNT_NO.getObj());
                }
                redis.del(Const.user.loginAdmin + o.getAccountId());
                //修改reidis
                o.setState(state);
                redis.set(Const.user.Admin + adminId, o);
                UserAccount ua = UserAccount.dao.findById(o.getAccountId());
                ua.setState(state);
                ua.update();
                
            }
        }
        
        return Ret.ok();
    }

    /**
     * 导出学生信息
     *
     * @return
     */
    public String exportStuLoginInfo() throws Exception {
        List<Record> recordList = Db.find("SELECT oc.`id`,oc.`name`,og.`id` gradeId,og.`name` gradeName FROM org_class oc INNER JOIN org_grade og ON oc.`adminGradeId` = og.`id`");
        HashMap<Integer, Record> hashMap = new HashMap<>();
        recordList.stream().forEach(record -> hashMap.put(record.getInt("id"), record));


        Cache redis = Redis.use();
        Prop testAccount = PropKit.use("testAccount.properties");
        String accountStr = testAccount.get("studentAccount");
        String[] accounts = accountStr.split(",");
        Set<String> keys = redis.keys(Const.user.Student + "*");
        ArrayList<Student> students = new ArrayList<>();
        for (String key : keys) {
            students.add(redis.get(key));
        }

        //查询所有学生信息
        ArrayList<StudentInfoDTO> studentInfoDTOS = new ArrayList<>(students.size() + 1);
        for (Student student : students) {
            if (Arrays.stream(accounts).anyMatch(student.getAccountId().toString()::equals)) {
                continue;
            }
            StudentInfoDTO studentInfoDTO = new StudentInfoDTO();
            studentInfoDTO.setAccount(student.getNumber());
            studentInfoDTO.setClasId(hashMap.get(student.getClasId()) == null ? "-" : hashMap.get(student.getClasId()).getStr("name"));
            studentInfoDTO.setName(student.getName());
            studentInfoDTO.setNumber(student.getNumber());
            studentInfoDTO.setSchoolYear(student.getSchoolYear());
            // LocalDateTime lastLoginTime = student.getLocalDateTime("lastLoginTime");
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            Long lastLoginTimestamp = student.getLong("lastLoginTimestamp");
            if (lastLoginTimestamp != 0) {
                Date date = new Date(lastLoginTimestamp);
                studentInfoDTO.setLastLoginTime(date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime().format(formatter));
            } else {
                studentInfoDTO.setLastLoginTime("无");
            }
            //   studentInfoDTO.setParent(redisStudent.get("parent"));
            studentInfoDTO.setTeacher(student.get("teacher"));
            studentInfoDTO.setExample(student.get("example"));
//            studentInfoDTO.setLastLoginTime(lastLoginTime == null ? "无" : lastLoginTime.format(formatter));
            studentInfoDTO.setGrade(hashMap.get(student.getClasId()) == null ? "-" : hashMap.get(student.getClasId()).getStr("gradeName"));
            studentInfoDTO.setIsLogin(student.getZScore() == 0 ? "否" : "是");
            studentInfoDTO.setIsSelectExample(studentInfoDTO.getExample() == null ? "否" : "是");
            studentInfoDTOS.add(studentInfoDTO);
        }
        String path = PathKit.getWebRootPath() + "/download/studentInfo_" + System.currentTimeMillis() + ".xlsx";
        ExcelWriter writer = null;
        try {
            writer = ExcelUtil.getWriter(path);
            writer.getStyleSet().setAlign(HorizontalAlignment.CENTER, VerticalAlignment.CENTER);
            writer.addHeaderAlias("account", "学籍号");
            writer.setColumnWidth(0, 20);
            writer.addHeaderAlias("number", "学号");
            writer.addHeaderAlias("name", "姓名");
            writer.addHeaderAlias("schoolYear", "届别");
            writer.addHeaderAlias("grade", "年级");
            //    writer.addHeaderAlias("parent","父母");
            writer.addHeaderAlias("teacher", "导师");
            writer.addHeaderAlias("example", "选择的榜样");
            writer.setColumnWidth(6, 21);
            writer.addHeaderAlias("clasId", "班级");
            writer.addHeaderAlias("isLogin", "是否登录");
            writer.addHeaderAlias("lastLoginTime", "上次登录时间");
            writer.setColumnWidth(7, 21);
            writer.addHeaderAlias("isSelectExample", "选择重要他人");
            writer.setColumnWidth(8, 15);
            writer.setColumnWidth(9, 21);
            writer.setColumnWidth(10, 21);
            writer.merge(10, "学生信息表");
            writer.write(studentInfoDTOS, true);
        } finally {
            //释放资源
            writer.close();
        }
        return path;
    }

    /**
     * 导出教师信息
     *
     * @return
     * @throws Exception
     */
    public String exportTeaInfo() throws Exception {
        List<Record> recordList = Db.find("SELECT oc.`id`,oc.`name`,og.`id` gradeId,og.`name` gradeName FROM org_class oc INNER JOIN org_grade og ON oc.`adminGradeId` = og.`id`");
        HashMap<Integer, Record> classHashMap = new HashMap<>();
        recordList.stream().forEach(record -> classHashMap.put(record.getInt("id"), record));

        Cache redis = Redis.use();
        Prop testAccount = PropKit.use("testAccount.properties");
        String accountStr = testAccount.get("adminAccount");
        String[] accounts = accountStr.split(",");
        Set<String> keys = redis.keys(Const.user.Admin + "*");
        ArrayList<Admin> adminArrayList = new ArrayList<>();
        for (String key : keys) {
            Admin o = redis.get(key);
            if (o.getUserType() == 1) {
                adminArrayList.add(redis.get(key));
            }
        }
        //查询所有教师信息
        List<Admin> admins = Admin.dao.find("select * from admin where id > 1 and isDele = 0");

        ArrayList<AdminInfoDTO> AdminDTOs = new ArrayList<>(admins.size() + 1);
        for (Admin admin : adminArrayList) {//{addTime:2022-08-18 15:26:05.0, gender:1, avatarUrl:null, isDele:false, subjects:null, updateTime:2023-01-05 17:15:31.0, version:1, timeStamp:0, lastLoginTime:null, accountId:1825, roleIds:[2], healther_teacher:false, user_type:1, job_num:TYF098, phone:+86-13310155695, name:鲁丹枫, id:100, state:1, email:}
            if (Arrays.stream(accounts).anyMatch(admin.getAccountId().toString()::equals)) {
                continue;
            }
            AdminInfoDTO adminInfoDTO = new AdminInfoDTO();
            adminInfoDTO.setAccount(admin.getJobNum());
            adminInfoDTO.setName(admin.getName());
            adminInfoDTO.setState(admin.getState() == 1 ? "正常" : "禁用");
            String roleIds = admin.getRoleIds();
            List<Integer> roleList = JSONUtil.toList(roleIds, Integer.class);
            String str = null;
            for (Integer roleId : roleList) {
                if (str == null) {
                    str = roleMap.get(roleId);
                } else {
                    str += "," + roleMap.get(roleId);
                }
            }
            adminInfoDTO.setRole(str);
            // Double zscore = redis.zscore(Const.user.lastLoginTimeT, admin.getId());
            Double zscore = admin.getDouble("timeStamp");
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            if (zscore != null && zscore != 0) {
                Date date = new Date(zscore.longValue());
                adminInfoDTO.setLastLoginTime(date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime().format(formatter));
            } else {
                adminInfoDTO.setLastLoginTime("无");
            }
            adminInfoDTO.setIsLoginApp(adminInfoDTO.getLastLoginTime().equals("无") ? "否" : "是");
            AdminDTOs.add(adminInfoDTO);
        }
        String path = PathKit.getWebRootPath() + "/download/teacherInfo_" + System.currentTimeMillis() + ".xlsx";
        ExcelWriter writer = null;
        try {
            writer = ExcelUtil.getWriter(path);
            writer.getStyleSet().setAlign(HorizontalAlignment.CENTER, VerticalAlignment.CENTER);
            writer.addHeaderAlias("account", "工号");
            writer.addHeaderAlias("name", "姓名");
            writer.addHeaderAlias("role", "角色");
            writer.addHeaderAlias("state", "状态");
            writer.addHeaderAlias("isLoginApp", "是否登录");
            writer.addHeaderAlias("lastLoginTime", "上次登录时间");
            writer.addHeaderAlias("permission", "数据权限");
            writer.setColumnWidth(5, 23);
            writer.setColumnWidth(6, 23);
            writer.setColumnWidth(2, 20);
            writer.merge(6, "教师信息表");
            CellStyle cs = writer.createCellStyle();
            cs.setWrapText(true);
            writer.write(AdminDTOs, true);
        } finally {
            //释放资源
            writer.close();
        }
        return path;
    }

    /**
     * 查询学生页面
     *
     * @param admin
     * @param page
     * @param limit
     * @return
     */
    public Ret studentPage(Admin admin, StudentPageDTO model, Integer page, Integer limit) throws Exception {
        Cache redis = Redis.use();
        //查询用户权限
        Set<Integer> frameworkPermission = admin.get("frameworkPermission");
        if (ObjectUtil.isAllEmpty(frameworkPermission)) {
            return Ret.ok("studentList", new ArrayList<Student>()).set("page", page).set("count", 0).set("totalrow", 0);
        }

        Set<String> keys = redis.keys(Const.user.Student + "*");
        ArrayList<String> list = new ArrayList<>(keys);
        List<Student> students = new ArrayList<Student>();
        for (String s : list) {
            students.add(redis.get(s));
        }
        //排除测试账号
        Prop use = PropKit.use("testAccount.properties");
        String studentAccount = use.get("studentAccount");
        String[] split = studentAccount.split(",");
        List<String> testAccountList = Arrays.asList(split);

        List<Student> studentList = students.stream().filter(
                student -> {
                    boolean flag = true;
                    //判断该学生是否在数据权限内
                    if (!frameworkPermission.contains(student.getClasId())) {
                        return false;
                    }

                    if (StrUtil.isNotBlank(model.getAccountValue())) {
                        flag = FilterUtil.filterStr(student.getNumber(), model.getAccountValue());
                        //     flag = student.getAccount().equals(model.getAccountValue());
                        if (!flag) {
                            return false;
                        }
                    }
                    if (StrUtil.isNotBlank(model.getClasIdValue())) {
                        flag = student.getClasId() == Integer.parseInt(model.getClasIdValue());
                        if (!flag) {
                            return false;
                        }
                    }
                    if (StrUtil.isNotBlank(model.getGradeIdValue())) {
                        flag = student.getGrade() == Integer.parseInt(model.getGradeIdValue());
                        if (!flag) {
                            return false;
                        }
                    }
                    if (StrUtil.isNotBlank(model.getNameValue())) {
                        flag = FilterUtil.filterStr(student.getName(), model.getNameValue());
//                        flag = student.getName().equals(model.getNameValue());
                        if (!flag) {
                            return false;
                        }
                    }
                    if (StrUtil.isNotBlank(model.getStateValue())) {
                        flag = student.getState() == Integer.parseInt(model.getStateValue());
                        if (!flag) {
                            return false;
                        }
                    }
                    if (StrUtil.isNotBlank(model.getNumberValue())) {
                        flag = FilterUtil.filterStr(student.getStudentNo(), model.getNumberValue());
//                      flag = student.getNumber().equals(model.getNumberValue());
                        if (!flag) {
                            return false;
                        }
                    }
                    if (StrUtil.isNotBlank(model.getSchoolYearValue())) {
                        flag = student.getSchoolYear().equals(model.getSchoolYearValue());
                        if (!flag) {
                            return false;
                        }
                    }
                    if (StrUtil.isNotBlank(model.getIsMainlandValue())) {
                        flag = student.getIsMainland() == (model.getIsMainlandValue() == "1");
                        if (!flag) {
                            return false;
                        }
                    }
                    if (StrUtil.isNotBlank(model.getSexValue())) {
                        flag = student.getSex() == Integer.parseInt(model.getSexValue());
                        if (!flag) {
                            return false;
                        }
                    }
                    if (StrUtil.isNotBlank(model.getTeacherValue())) {
                        flag = FilterUtil.filterStr(student.get("teacher"), model.getTeacherValue());
//                        flag = model.getTeacherValue().equals(student.get("teacher"));
                        if (!flag) {
                            return false;
                        }
                    }
                    if (model.getIsLoginValue() != null) {
                        boolean b = model.getIsLoginValue() == (student.getZScore() > 0);
                        return b;
                    }
                    if (student.getIsDele() != null && student.getIsDele()) {
                        return false;
                    }
                    if (testAccountList.contains(student.getAccountId().toString())) {
                        return false;
                    }
                    return flag;
                }
        ).map(student ->
                {
                    if (model.getLastLoginTime() == null || !model.getLastLoginTime()) {
                        student.remove("lastLoginTime");
                    }
                    if (model.getState() == null || !model.getState()) {
                        student.remove("state");
                    }
                    if (model.getTeacher() == null || !model.getTeacher()) {
                        student.remove("teacher");
                        student.remove("teacherId");
                    }
                    if (model.getExample() == null || !model.getExample()) {
                        student.remove("example");
                    }
                    if (model.getIsLogin() != null && model.getIsLogin()) {
                        Integer zScore = student.getZScore();
                        student.put("isLogin", !(zScore == 0));
                    }
                    if (model.getzScore() == null || !model.getzScore()) {
                        student.remove("zScore");
                    }
                    if (model.getParent() == null || !model.getParent()) {
                        student.remove("parent");
                    }
                    student.remove("salt");
                    return student;
                }
        ).sorted((e1, e2) -> {
            if (model.getStudentNoSort() != null) {
                if (model.getStudentNoSort().equalsIgnoreCase("ASC")) {
                    return Integer.parseInt(e1.getStudentNo()) - Integer.parseInt(e2.getStudentNo());
                } else {
                    return Integer.parseInt(e2.getStudentNo()) - Integer.parseInt(e1.getStudentNo());
                }
            }
            if (model.getzScoreSort() != null) {
                if (model.getzScoreSort().equalsIgnoreCase("ASC")) {
                    return e1.getZScore() - e2.getZScore();
                } else {
                    return e2.getZScore() - e1.getZScore();
                }
            }
//            if (model.getAwardNumSort() != null) {
//                if (model.getAwardNumSort().equalsIgnoreCase("ASC")) {
//                    return e1.getInt("awardNum") - e2.getInt("awardNum");
//                } else {
//                    return e2.getInt("awardNum") - e1.getInt("awardNum");
//                }
//            }
            if (model.getLastLoginTimeSort() != null) {
            	
            	Double zscore1 = redis.zscore(Const.user.lastLoginTimeS, e1.getId());
            	Double zscore2 = redis.zscore(Const.user.lastLoginTimeS, e2.getId());
                if (model.getLastLoginTimeSort().equalsIgnoreCase("ASC")) {
//                    return (int) (e1.getLong("lastLoginTimestamp") / 1000 - e2.getLong("lastLoginTimestamp") / 1000);
                	return (int) ((zscore1==null?0:zscore1) / 1000 - (zscore2==null?0:zscore2) / 1000);
                } else {
//                    return (int) (e2.getLong("lastLoginTimestamp") / 1000 - e1.getLong("lastLoginTimestamp") / 1000);
                	return (int) ((zscore2==null?0:zscore2) / 1000 - (zscore1==null?0:zscore1) / 1000);
                }
            }
            return e2.getId() - e1.getId();
        }).collect(Collectors.toList());
        int count = studentList.size();
        List<Student> resultList = studentList.stream().skip((page - 1) * limit).limit(limit).collect(Collectors.toList());
        if (model.getScoreRank() != null && model.getScoreRank()) {
            for (Student student : resultList) {
                Long zrank = redis.zrevrank(Const.user.StudentScore, student.getId());
                student.put("scoreRank", zrank + 1);
            }
        }
        if (model.getLastLoginTime() != null && model.getLastLoginTime()) {
            for (int i = 0; i < resultList.size(); i++) {
                Student student = resultList.get(i);
                Double zscore = redis.zscore(Const.user.lastLoginTimeS, student.getId());
                //student.getLong("lastLoginTimestamp");
                if (zscore != null && zscore.intValue() != 0) {//lastLoginTimestamp != 0
                	Long lastLoginTimestamp = zscore.longValue();
                    Date date = new Date(lastLoginTimestamp);
                    student.setLastLoginTime(date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime());
                }
            }
        }
        //登录时长
        if (model.getLoginDuration() != null && model.getLoginDuration()) {
            for (int i = 0; i < resultList.size(); i++) {
                Student student = resultList.get(i);
                String loginDurationValue = model.getLoginDurationValue();
                int loginDuration = Integer.parseInt(loginDurationValue);
                //查询登录时间
                Long startTime = null;
                Long endTime = System.currentTimeMillis() / 1000;
                if (loginDuration == 2) {
                    Calendar calendar = Calendar.getInstance();
                    calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH) - 1, 0, 0, 0);
                    startTime = calendar.getTime().getTime() / 1000;
                    Calendar instance = Calendar.getInstance();
                    instance.set(instance.get(Calendar.YEAR), instance.get(Calendar.MONTH), instance.get(Calendar.DAY_OF_MONTH), 0, 0, 0);
                    endTime = instance.getTime().getTime() / 1000;
                } else if (loginDuration == 3) {
                    Calendar calendar = Calendar.getInstance();
                    calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH) - 6, 0, 0, 0);
                    startTime = calendar.getTime().getTime() / 1000;
                } else if (loginDuration == 4) {
                    Calendar calendar = Calendar.getInstance();
                    calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH) - 29, 0, 0, 0);
                    startTime = calendar.getTime().getTime() / 1000;
                } else {
                    long current = System.currentTimeMillis();
                    startTime = (current - (current + TimeZone.getDefault().getRawOffset()) % (1000 * 3600 * 24)) / 1000;
                }
                int statisticsUseTime = InfluxDbKit.statisticsUseTime("slog", student.getId(), startTime.toString(), endTime.toString());
                student.put("loginDuration", statisticsUseTime + "min");
            }
        }

        return Ret.ok("studentList", resultList).set("page", page).set("count", count % limit == 0 ? count / limit : count / limit + 1).set("totalrow", count);
    }

    /**
     * 查询届别班级
     *
     * @param admin
     * @return
     */
    public Ret findClassInfo(Admin admin) {
        List<Record> schoolYearList = null;
        List<Record> clasIdList = null;
        //查询学生届别班级
        schoolYearList = Db.find("SELECT DISTINCT schoolYear FROM student WHERE isDele = 0");
        for (Record record : schoolYearList) {
            clasIdList = Db.find("SELECT DISTINCT clasId FROM student WHERE isDele = 0 AND schoolYear = ? ", record.getStr("schoolYear"));
            record.put("clasId", clasIdList);
        }

        return Ret.ok("schoolYearList", schoolYearList);
    }

    /**
     * 批量启用/禁用
     *
     * @param studentIds
     * @param state
     * @return
     */
//    public Ret batchUpdate(Admin admin, String studentIds, Integer state) {
//        Set<Integer> frameworkPermission = admin.get("frameworkPermission");
//        List<Integer> studentIdList = JSONUtil.toList(studentIds, Integer.class);
//        ArrayList<Student> students = new ArrayList<>(studentIdList.size());
//        for (int i = 0; i < studentIdList.size(); i++) {
//            Student student = Student.dao.findById(studentIdList.get(i));
//            if (BeanUtil.isEmpty(student)) {
//                continue;
//            }
//            //判断当前教师是否有当前学生的权限
//            if (!frameworkPermission.contains(student.getClasId())) {
//                return Ret.fail().set("error", EnumError.NOT_HAVE_AUTHORITY.getObj());
//            }
//            student.setState(state);
//            students.add(student);
//        }
//        Db.batchUpdate(students, students.size());
//        //更新redis数据
//        Cache redis = Redis.use();
//        for (int i = 0; i < studentIdList.size(); i++) {
//            Student student = redis.get(Const.user.Student + studentIdList.get(i));
//            student.setState(state);
//            redis.set(Const.user.Student + studentIdList.get(i), student);
//        }
//
//        return Ret.ok();
//    }

    /**
     * 查询家长列表
     *
     * @param admin
     * @param studentName
     * @param schoolYear
     * @param lastLoginTimeSort
     * @param state
     * @return
     */
    public Ret parentPage(Admin admin, String studentName, String schoolYear, String lastLoginTimeSort, Integer
            state, Integer clasId, String account, String role, Integer page, Integer limit) {

        Kv kv = Kv.create().setIfNotNull("studentName", studentName).setIfNotNull("schoolYear", schoolYear)
                .setIfNotNull("lastLoginTimeSort", lastLoginTimeSort).setIfNotNull("state", state)
                .setIfNotNull("clasId", clasId).setIfNotNull("account", account).setIfNotNull("role", role);
        //查询家长
        List<Record> records = Db.template("findParent", kv).find();
        records = new ArrayList<Record>(new LinkedHashSet<>(records));
        for (Record record : records) {
            Integer id = record.getInt("id");
            kv.set("id", id);
            List<Record> list = Db.template("parentStudnet", kv).find();
            record.put("students", list);
        }
        int count = records.size();
        List<Record> recordsList = records.stream().skip((page - 1) * limit).limit(limit).collect(Collectors.toList());
        return Ret.ok("parentList", recordsList).set("page", page).set("count", count % limit == 0 ? count / limit : count / limit + 1).set("totalrow", count);
    }


    /**
     * 获取学年
     *
     * @param admin
     * @return
     */
    public Ret getSchoolYear(Admin admin) {

        List<Student> students = Student.dao.find("SELECT distinct schoolYear FROM student WHERE isDele = 0 ORDER BY schoolYear");
        ArrayList<String> list = new ArrayList<>();
        if (LocalDateTime.now().getMonthValue() >= 9) {
            list.add(LocalDateTime.now().getYear() + 1 + "届");
            list.add(LocalDateTime.now().getYear() + 2 + "届");
            list.add(LocalDateTime.now().getYear() + 3 + "届");
        } else {
            list.add(LocalDateTime.now().getYear() + "届");
            list.add(LocalDateTime.now().getYear() + 1 + "届");
            list.add(LocalDateTime.now().getYear() + 2 + "届");
        }
        return Ret.ok().set("findSchoolYear", students).set("createSchoolYear", list);
    }

    /**
     * 禁用/启用家长
     *
     * @param admin
     * @param state
     * @param parentIds
     * @return
     */
    public Ret updateStateParent(Admin admin, Integer state, String parentIds) {
        //批量更新
        List<Integer> parentIdList = JSONUtil.toList(parentIds, Integer.class);
        ArrayList<Parent> parents = new ArrayList<Parent>(parentIdList.size());
        for (int i = 0; i < parentIdList.size(); i++) {
            Integer parentId = parentIdList.get(i);
            Parent parent = Parent.dao.findById(parentId);
            parent.setState(state);
            parents.add(parent);
        }
        Db.batchUpdate(parents, parents.size());
        return Ret.ok();
    }

    /**
     * 删除家长
     *
     * @param admin
     * @param parentIds
     * @return
     */
    public Ret delParent(Admin admin, String parentIds) {
        List<Integer> parentList = JSONUtil.toList(parentIds, Integer.class);
        ArrayList<Parent> parents = new ArrayList<>(parentList.size());
        for (int i = 0; i < parentList.size(); i++) {
            Integer parId = parentList.get(i);
            Parent parent = Parent.dao.findById(parId);
            parent.setIsDelete(true);
            parent.setUpdateTime(LocalDateTime.now());
            parents.add(parent);
        }
        Db.batchUpdate(parents, parents.size());

        return Ret.ok();
    }

    /**
     * 导出家长信息
     *
     * @return
     */
    public String exportParentInfo() {

        List<Record> recordList = Db.find("SELECT oc.`id`,oc.`name`,og.`id` gradeId,og.`name` gradeName FROM org_class oc INNER JOIN org_grade og ON oc.`adminGradeId` = og.`id`");
        HashMap<Integer, Record> hashMap = new HashMap<>();
        recordList.stream().forEach(record -> hashMap.put(record.getInt("id"), record));
        //查询所有教师信息
        List<Parent> parents = Parent.dao.find("SELECT id,wxNickname,role,lastLogin,state,name FROM parent WHERE isDelete = 0");
        ArrayList<ParentInfoDTO> parentInfoDTOS = new ArrayList<>(parents.size() + 1);
        for (Parent parent : parents) {
            ParentInfoDTO parentInfoDTO = new ParentInfoDTO();
            parentInfoDTO.setWxNickname(parent.getWxNickname());
            parentInfoDTO.setRole(parent.getRole());
            parentInfoDTO.setState(parent.getState() == 1 ? "正常" : "禁用");
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            LocalDateTime lastLoginTime = parent.getLastLogin();
            parentInfoDTO.setLastLoginTime(lastLoginTime == null ? "无" : lastLoginTime.format(formatter));
            parentInfoDTO.setName(parent.getName());
            Kv kv = Kv.by("id", parent.getId());
            List<Student> list = Student.dao.template("parentStudnet", kv).find();
            String str = "";
            if (list != null && list.size() > 0) {
                for (int i = 0; i < list.size(); i++) {
                    Student student = list.get(i);
                    if (i == 0) {
                        str += student.getNumber();
                        str += "," + student.getName();
                        str += "," + student.getSchoolYear();
                        str += "," + hashMap.get(student.getClasId()) == null ? "-" : hashMap.get(student.getClasId()).getStr("gradeName") + hashMap.get(student.getClasId()) == null ? "-" : hashMap.get(student.getClasId()).getStr("name");
                    } else {
                        str += "\r\n " + student.getNumber();
                        str += "," + student.getName();
                        str += "," + student.getSchoolYear();
                        str += "," + hashMap.get(student.getClasId()) == null ? "-" : hashMap.get(student.getClasId()).getStr("gradeName") + hashMap.get(student.getClasId()) == null ? "-" : hashMap.get(student.getClasId()).getStr("name");
                    }
                }
                parentInfoDTO.setStudents(str);
                parentInfoDTOS.add(parentInfoDTO);
            }
        }
        String path = PathKit.getWebRootPath() + "/download/parentInfo_" + System.currentTimeMillis() + ".xlsx";
        ExcelWriter writer = null;
        try {
            writer = ExcelUtil.getWriter(path);
            writer.getStyleSet().setAlign(HorizontalAlignment.CENTER, VerticalAlignment.CENTER);
            writer.addHeaderAlias("wxNickname", "微信昵称");
            writer.addHeaderAlias("name", "家长姓名");
            writer.addHeaderAlias("role", "角色");
            writer.addHeaderAlias("lastLoginTime", "上次登录时间");
            writer.addHeaderAlias("students", "绑定学生");
            writer.addHeaderAlias("state", "状态");
            writer.addHeaderAlias("students", "绑定学生信息");
            writer.setColumnWidth(3, 25);
            writer.setColumnWidth(4, 50);
            writer.setColumnWidth(0, 20);
            writer.merge(5, "家长信息表");
            writer.write(parentInfoDTOS, true);
        } finally {
            //释放资源
            writer.close();
        }
        return path;
    }

    
    public Ret addExternalInfo(){
    	
    	
    	
    	return Ret.ok();
    }
    
}
